
#pragma once

namespace Blake
{
    ref class Blake abstract
    {
        protected:

            #pragma region Consts

            static array<byte>^ padding =
            {
                0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
                0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
            };

            static array<byte>^ ending = { 0x00, 0x01, 0x80, 0x81 };

            #pragma endregion

            int m_hashSize;
            bool m_nullt;
            int m_buffer_pos;
            ulong m_processedBytes;

            virtual void Finish() = 0;
            virtual array<byte>^ GetResult() = 0;
            virtual void TransformBlock(array<byte>^ a_data, int a_index) = 0;

        public:

            Blake(int a_hashSize) : m_hashSize(a_hashSize)
            {
            }

            array<byte>^ TransformFinal()
            {
                Finish();
                array<byte>^ result = GetResult();
                Initialize();
                return result;
            }

            virtual void Initialize()
            {
                m_processedBytes = 0;
                m_buffer_pos = 0;
                m_nullt = false;
            }

            array<byte>^ ComputeBytes(array<byte>^ a_data)
            {
                Initialize();
                TransformBytes(a_data, 0, a_data->Length);
                return TransformFinal();
            }

            virtual void TransformBytes(array<byte>^ a_data, int a_index, int a_length) = 0;
    };

    ref class Blake256 : public Blake
    {
        private:

            #pragma region Consts

            static array<uint>^ m_initial_state_256 =
            {
                0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
            };

            static array<uint>^ m_initial_state_224 =
            {
                0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4
            };

            #pragma endregion

        protected:

            array<uint>^ m_state;
            array<byte>^ m_buffer;

            virtual void TransformBlock(array<byte>^ a_data, int a_index) override
            {
                uint m0 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 0);
                uint m1 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 1);
                uint m2 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 2);
                uint m3 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 3);
                uint m4 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 4);
                uint m5 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 5);
                uint m6 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 6);
                uint m7 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 7);
                uint m8 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 8);
                uint m9 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 9);
                uint m10 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 10);
                uint m11 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 11);
                uint m12 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 12);
                uint m13 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 13);
                uint m14 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 14);
                uint m15 = Converters::ConvertBytesToUIntSwapOrder(a_data, a_index + 4 * 15);

                const uint c32_0 = 0x243F6A88;
                const uint c32_1 = 0x85A308D3;
                const uint c32_2 = 0x13198A2E;
                const uint c32_3 = 0x03707344;
                const uint c32_4 = 0xA4093822;
                const uint c32_5 = 0x299F31D0;
                const uint c32_6 = 0x082EFA98;
                const uint c32_7 = 0xEC4E6C89;
                const uint c32_8 = 0x452821E6;
                const uint c32_9 = 0x38D01377;
                const uint c32_10 = 0xBE5466CF;
                const uint c32_11 = 0x34E90C6C;
                const uint c32_12 = 0xC0AC29B7;
                const uint c32_13 = 0xC97C50DD;
                const uint c32_14 = 0x3F84D5B5;
                const uint c32_15 = 0xB5470917;

                uint v0 = m_state[0];
                uint v1 = m_state[1];
                uint v2 = m_state[2];
                uint v3 = m_state[3];
                uint v4 = m_state[4];
                uint v5 = m_state[5];
                uint v6 = m_state[6];
                uint v7 = m_state[7];
                uint v8 = c32_0;
                uint v9 = c32_1;
                uint v10 = c32_2;
                uint v11 = c32_3;
                uint v12 = c32_4;
                uint v13 = c32_5;
                uint v14 = c32_6;
                uint v15 = c32_7;

                if (!m_nullt)
                {
                    ulong bits = m_processedBytes * 8;
                    v12 ^= (uint)bits;
                    v13 ^= (uint)bits;
                    bits >>= 32;
                    v14 ^= (uint)bits;
                    v15 ^= (uint)bits;
                }

                v0 = v0 + v4 + (m0 ^ c32_1);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m1 ^ c32_0);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m2 ^ c32_3);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m3 ^ c32_2);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m4 ^ c32_5);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m5 ^ c32_4);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m6 ^ c32_7);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m7 ^ c32_6);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m8 ^ c32_9);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m9 ^ c32_8);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m10 ^ c32_11);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m11 ^ c32_10);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m12 ^ c32_13);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m13 ^ c32_12);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m14 ^ c32_15);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m15 ^ c32_14);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m14 ^ c32_10);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m10 ^ c32_14);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m4 ^ c32_8);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m8 ^ c32_4);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m9 ^ c32_15);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m15 ^ c32_9);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m13 ^ c32_6);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m6 ^ c32_13);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m1 ^ c32_12);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m12 ^ c32_1);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m0 ^ c32_2);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m2 ^ c32_0);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m11 ^ c32_7);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m7 ^ c32_11);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m5 ^ c32_3);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m3 ^ c32_5);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m11 ^ c32_8);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m8 ^ c32_11);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m12 ^ c32_0);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m0 ^ c32_12);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m5 ^ c32_2);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m2 ^ c32_5);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m15 ^ c32_13);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m13 ^ c32_15);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m10 ^ c32_14);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m14 ^ c32_10);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m3 ^ c32_6);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m6 ^ c32_3);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m7 ^ c32_1);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m1 ^ c32_7);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m9 ^ c32_4);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m4 ^ c32_9);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m7 ^ c32_9);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m9 ^ c32_7);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m3 ^ c32_1);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m1 ^ c32_3);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m13 ^ c32_12);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m12 ^ c32_13);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m11 ^ c32_14);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m14 ^ c32_11);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m2 ^ c32_6);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m6 ^ c32_2);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m5 ^ c32_10);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m10 ^ c32_5);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m4 ^ c32_0);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m0 ^ c32_4);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m15 ^ c32_8);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m8 ^ c32_15);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m9 ^ c32_0);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m0 ^ c32_9);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m5 ^ c32_7);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m7 ^ c32_5);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m2 ^ c32_4);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m4 ^ c32_2);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m10 ^ c32_15);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m15 ^ c32_10);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m14 ^ c32_1);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m1 ^ c32_14);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m11 ^ c32_12);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m12 ^ c32_11);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m6 ^ c32_8);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m8 ^ c32_6);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m3 ^ c32_13);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m13 ^ c32_3);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m2 ^ c32_12);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m12 ^ c32_2);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m6 ^ c32_10);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m10 ^ c32_6);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m0 ^ c32_11);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m11 ^ c32_0);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m8 ^ c32_3);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m3 ^ c32_8);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m4 ^ c32_13);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m13 ^ c32_4);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m7 ^ c32_5);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m5 ^ c32_7);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m15 ^ c32_14);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m14 ^ c32_15);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m1 ^ c32_9);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m9 ^ c32_1);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m12 ^ c32_5);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m5 ^ c32_12);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m1 ^ c32_15);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m15 ^ c32_1);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m14 ^ c32_13);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m13 ^ c32_14);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m4 ^ c32_10);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m10 ^ c32_4);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m0 ^ c32_7);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m7 ^ c32_0);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m6 ^ c32_3);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m3 ^ c32_6);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m9 ^ c32_2);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m2 ^ c32_9);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m8 ^ c32_11);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m11 ^ c32_8);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m13 ^ c32_11);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m11 ^ c32_13);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m7 ^ c32_14);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m14 ^ c32_7);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m12 ^ c32_1);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m1 ^ c32_12);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m3 ^ c32_9);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m9 ^ c32_3);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m5 ^ c32_0);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m0 ^ c32_5);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m15 ^ c32_4);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m4 ^ c32_15);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m8 ^ c32_6);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m6 ^ c32_8);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m2 ^ c32_10);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m10 ^ c32_2);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m6 ^ c32_15);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m15 ^ c32_6);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m14 ^ c32_9);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m9 ^ c32_14);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m11 ^ c32_3);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m3 ^ c32_11);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m0 ^ c32_8);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m8 ^ c32_0);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m12 ^ c32_2);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m2 ^ c32_12);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m13 ^ c32_7);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m7 ^ c32_13);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m1 ^ c32_4);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m4 ^ c32_1);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m10 ^ c32_5);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m5 ^ c32_10);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m10 ^ c32_2);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m2 ^ c32_10);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m8 ^ c32_4);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m4 ^ c32_8);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m7 ^ c32_6);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m6 ^ c32_7);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m1 ^ c32_5);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m5 ^ c32_1);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m15 ^ c32_11);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m11 ^ c32_15);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m9 ^ c32_14);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m14 ^ c32_9);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m3 ^ c32_12);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m12 ^ c32_3);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m13 ^ c32_0);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m0 ^ c32_13);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m0 ^ c32_1);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m1 ^ c32_0);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m2 ^ c32_3);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m3 ^ c32_2);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m4 ^ c32_5);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m5 ^ c32_4);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m6 ^ c32_7);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m7 ^ c32_6);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m8 ^ c32_9);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m9 ^ c32_8);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m10 ^ c32_11);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m11 ^ c32_10);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m12 ^ c32_13);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m13 ^ c32_12);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m14 ^ c32_15);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m15 ^ c32_14);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m14 ^ c32_10);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m10 ^ c32_14);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m4 ^ c32_8);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m8 ^ c32_4);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m9 ^ c32_15);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m15 ^ c32_9);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m13 ^ c32_6);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m6 ^ c32_13);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m1 ^ c32_12);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m12 ^ c32_1);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m0 ^ c32_2);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m2 ^ c32_0);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m11 ^ c32_7);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m7 ^ c32_11);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m5 ^ c32_3);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m3 ^ c32_5);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m11 ^ c32_8);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m8 ^ c32_11);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m12 ^ c32_0);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m0 ^ c32_12);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m5 ^ c32_2);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m2 ^ c32_5);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m15 ^ c32_13);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m13 ^ c32_15);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m10 ^ c32_14);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m14 ^ c32_10);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m3 ^ c32_6);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m6 ^ c32_3);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m7 ^ c32_1);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m1 ^ c32_7);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m9 ^ c32_4);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m4 ^ c32_9);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                v0 = v0 + v4 + (m7 ^ c32_9);
                v12 = ((v12 ^ v0) << 16) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 20) | ((v4 ^ v8) >> 12);
                v0 = v0 + v4 + (m9 ^ c32_7);
                v12 = ((v12 ^ v0) << 24) | ((v12 ^ v0) >> 8);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 25) | ((v4 ^ v8) >> 7);

                v1 = v1 + v5 + (m3 ^ c32_1);
                v13 = ((v13 ^ v1) << 16) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 20) | ((v5 ^ v9) >> 12);
                v1 = v1 + v5 + (m1 ^ c32_3);
                v13 = ((v13 ^ v1) << 24) | ((v13 ^ v1) >> 8);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 25) | ((v5 ^ v9) >> 7);

                v2 = v2 + v6 + (m13 ^ c32_12);
                v14 = ((v14 ^ v2) << 16) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 20) | ((v6 ^ v10) >> 12);
                v2 = v2 + v6 + (m12 ^ c32_13);
                v14 = ((v14 ^ v2) << 24) | ((v14 ^ v2) >> 8);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 25) | ((v6 ^ v10) >> 7);

                v3 = v3 + v7 + (m11 ^ c32_14);
                v15 = ((v15 ^ v3) << 16) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 20) | ((v7 ^ v11) >> 12);
                v3 = v3 + v7 + (m14 ^ c32_11);
                v15 = ((v15 ^ v3) << 24) | ((v15 ^ v3) >> 8);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 25) | ((v7 ^ v11) >> 7);

                v0 = v0 + v5 + (m2 ^ c32_6);
                v15 = ((v15 ^ v0) << 16) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 20) | ((v5 ^ v10) >> 12);
                v0 = v0 + v5 + (m6 ^ c32_2);
                v15 = ((v15 ^ v0) << 24) | ((v15 ^ v0) >> 8);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 25) | ((v5 ^ v10) >> 7);

                v1 = v1 + v6 + (m5 ^ c32_10);
                v12 = ((v12 ^ v1) << 16) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 20) | ((v6 ^ v11) >> 12);
                v1 = v1 + v6 + (m10 ^ c32_5);
                v12 = ((v12 ^ v1) << 24) | ((v12 ^ v1) >> 8);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 25) | ((v6 ^ v11) >> 7);

                v2 = v2 + v7 + (m4 ^ c32_0);
                v13 = ((v13 ^ v2) << 16) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 20) | ((v7 ^ v8) >> 12);
                v2 = v2 + v7 + (m0 ^ c32_4);
                v13 = ((v13 ^ v2) << 24) | ((v13 ^ v2) >> 8);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 25) | ((v7 ^ v8) >> 7);

                v3 = v3 + v4 + (m15 ^ c32_8);
                v14 = ((v14 ^ v3) << 16) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 20) | ((v4 ^ v9) >> 12);
                v3 = v3 + v4 + (m8 ^ c32_15);
                v14 = ((v14 ^ v3) << 24) | ((v14 ^ v3) >> 8);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 25) | ((v4 ^ v9) >> 7);

                m_state[0] ^= v0 ^ v8;
                m_state[1] ^= v1 ^ v9;
                m_state[2] ^= v2 ^ v10;
                m_state[3] ^= v3 ^ v11;
                m_state[4] ^= v4 ^ v12;
                m_state[5] ^= v5 ^ v13;
                m_state[6] ^= v6 ^ v14;
                m_state[7] ^= v7 ^ v15;
            }

            virtual array<byte>^ GetResult() override
            {
                return Converters::ConvertUIntsToBytesSwapOrder(m_state, 0, m_hashSize/4);
            }

            virtual void Finish() override
            {
                ulong bits = m_processedBytes * 8;

                if (m_buffer_pos == 55) 
                {
                    m_processedBytes -= 1;
                    if (m_hashSize == 28) 
                        TransformBytes(ending, 2, 1);
                    else
                        TransformBytes(ending, 3, 1);
                }
                else 
                {
                    if (m_buffer_pos < 55) 
                    {
                        if (m_buffer_pos == 0) 
                            m_nullt=true;
                        m_processedBytes -= (55 - m_buffer_pos);
                        TransformBytes(padding, 0, 55 - m_buffer_pos);
                    }
                    else 
                    {
                        m_processedBytes -= (64 - m_buffer_pos);
                        TransformBytes(padding, 0, 64 - m_buffer_pos);
                        m_processedBytes -= 55;
                        TransformBytes(padding, 1, 55);
                        m_nullt = true;
                    }
                    if (m_hashSize == 28) 
                        TransformBytes(ending, 0, 1);
                    else
                        TransformBytes(ending, 1, 1);

                    m_processedBytes -= 1;
                }

                m_processedBytes -= 8;

                array<byte>^ msg = gcnew array<byte>(8);
                msg[0] = (byte)(bits >> 56);
                msg[1] = (byte)(bits >> 48);
                msg[2] = (byte)(bits >> 40);
                msg[3] = (byte)(bits >> 32);
                msg[4] = (byte)(bits >> 24);
                msg[5] = (byte)(bits >> 16);
                msg[6] = (byte)(bits >> 8);
                msg[7] = (byte)bits;

                TransformBytes(msg, 0, 8);   
            }

        public:

            Blake256(int a_hashSize)
                : Blake(a_hashSize)
            {
                Debug::Assert((a_hashSize == 28) || (a_hashSize == 32));

                m_state = gcnew array<uint>(8);
                m_buffer = gcnew array<byte>(64);

                Initialize();
            }

            virtual void Initialize() override
            {
                if (m_hashSize == 28) 
                    Buffer::BlockCopy(m_initial_state_224, 0, m_state, 0, 32);
                else 
                    Buffer::BlockCopy(m_initial_state_256, 0, m_state, 0, 32);

                Array::Clear(m_buffer, 0, 64);

                Blake::Initialize();
            }

            virtual void TransformBytes(array<byte>^ a_data, int a_index, int a_length) override
            {
                if ((a_length == 0) && (m_buffer_pos != 64))
                    return;

                int left = m_buffer_pos; 
                int fill = 64 - left;

                if (left && ((a_length & 0x3F) >= fill)) 
                {
                    Array::Copy(a_data, a_index, m_buffer, left, fill);

                    m_processedBytes += fill;

                    TransformBlock(m_buffer, 0);
                    a_index += fill;
                    a_length  -= fill; 

                    left = 0;
                    m_buffer_pos = 0;
                }

                while (a_length >= 64) 
                {
                    m_processedBytes += 64;

                    TransformBlock(a_data, a_index);
                    a_index += 64;
                    a_length  -= 64;
                }

                if(a_length > 0) 
                {
                    Array::Copy(a_data, a_index, m_buffer, left, a_length);
                    m_buffer_pos = left + a_length;
                    m_processedBytes += a_length;
                }
                else
                    m_buffer_pos = 0;
            }
    };

    ref class Blake512 : public Blake
    {
        private:

            #pragma region Consts

            static array<ulong>^ m_initial_state_384 =
            {
                0xCBBB9D5DC1059ED8, 0x629A292A367CD507, 0x9159015A3070DD17, 0x152FECD8F70E5939,
                0x67332667FFC00B31, 0x8EB44A8768581511, 0xDB0C2E0D64F98FA7, 0x47B5481DBEFA4FA4
            };

            static array<ulong>^ m_initial_state_512 =
            {
                0x6A09E667F3BCC908, 0xBB67AE8584CAA73B, 0x3C6EF372FE94F82B, 0xA54FF53A5F1D36F1,
                0x510E527FADE682D1, 0x9B05688C2B3E6C1F, 0x1F83D9ABFB41BD6B, 0x5BE0CD19137E2179
            };

            #pragma endregion

        protected:

            array<ulong>^ m_state;
            array<byte>^ m_buffer;

            virtual void TransformBlock(array<byte>^ a_data, int a_index) override
            {
                ulong m0 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 0);
                ulong m1 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 1);
                ulong m2 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 2);
                ulong m3 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 3);
                ulong m4 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 4);
                ulong m5 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 5);
                ulong m6 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 6);
                ulong m7 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 7);
                ulong m8 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 8);
                ulong m9 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 9);
                ulong m10 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 10);
                ulong m11 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 11);
                ulong m12 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 12);
                ulong m13 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 13);
                ulong m14 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 14);
                ulong m15 = Converters::ConvertBytesToULongSwapOrder(a_data, a_index + 8 * 15);

                const ulong c64_0 = 0x243F6A8885A308D3;
                const ulong c64_1 = 0x13198A2E03707344;
                const ulong c64_2 = 0xA4093822299F31D0;
                const ulong c64_3 = 0x082EFA98EC4E6C89;
                const ulong c64_4 = 0x452821E638D01377;
                const ulong c64_5 = 0xBE5466CF34E90C6C;
                const ulong c64_6 = 0xC0AC29B7C97C50DD;
                const ulong c64_7 = 0x3F84D5B5B5470917;
                const ulong c64_8 = 0x9216D5D98979FB1B;
                const ulong c64_9 = 0xD1310BA698DFB5AC;
                const ulong c64_10 = 0x2FFD72DBD01ADFB7;
                const ulong c64_11 = 0xB8E1AFED6A267E96;
                const ulong c64_12 = 0xBA7C9045F12C7F99;
                const ulong c64_13 = 0x24A19947B3916CF7;
                const ulong c64_14 = 0x0801F2E2858EFC16;
                const ulong c64_15 = 0x636920D871574E69;

                ulong v0 = m_state[0];
                ulong v1 = m_state[1];
                ulong v2 = m_state[2];
                ulong v3 = m_state[3];
                ulong v4 = m_state[4];
                ulong v5 = m_state[5];
                ulong v6 = m_state[6];
                ulong v7 = m_state[7];
                ulong v8 = c64_0;
                ulong v9 = c64_1;
                ulong v10 = c64_2;
                ulong v11 = c64_3;
                ulong v12 = c64_4;
                ulong v13 = c64_5;
                ulong v14 = c64_6;
                ulong v15 = c64_7;

                if (!m_nullt)
                {
                    ulong bits = m_processedBytes * 8;
                    v12 ^= bits;
                    v13 ^= bits;
                }

                v0 = v0 + v4 + (m0 ^ c64_1);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m1 ^ c64_0);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m2 ^ c64_3);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m3 ^ c64_2);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m4 ^ c64_5);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m5 ^ c64_4);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m6 ^ c64_7);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m7 ^ c64_6);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m8 ^ c64_9);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m9 ^ c64_8);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m10 ^ c64_11);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m11 ^ c64_10);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m12 ^ c64_13);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m13 ^ c64_12);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m14 ^ c64_15);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m15 ^ c64_14);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m14 ^ c64_10);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m10 ^ c64_14);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m4 ^ c64_8);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m8 ^ c64_4);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m9 ^ c64_15);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m15 ^ c64_9);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m13 ^ c64_6);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m6 ^ c64_13);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m1 ^ c64_12);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m12 ^ c64_1);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m0 ^ c64_2);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m2 ^ c64_0);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m11 ^ c64_7);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m7 ^ c64_11);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m5 ^ c64_3);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m3 ^ c64_5);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m11 ^ c64_8);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m8 ^ c64_11);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m12 ^ c64_0);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m0 ^ c64_12);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m5 ^ c64_2);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m2 ^ c64_5);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m15 ^ c64_13);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m13 ^ c64_15);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m10 ^ c64_14);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m14 ^ c64_10);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m3 ^ c64_6);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m6 ^ c64_3);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m7 ^ c64_1);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m1 ^ c64_7);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m9 ^ c64_4);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m4 ^ c64_9);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m7 ^ c64_9);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m9 ^ c64_7);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m3 ^ c64_1);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m1 ^ c64_3);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m13 ^ c64_12);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m12 ^ c64_13);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m11 ^ c64_14);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m14 ^ c64_11);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m2 ^ c64_6);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m6 ^ c64_2);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m5 ^ c64_10);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m10 ^ c64_5);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m4 ^ c64_0);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m0 ^ c64_4);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m15 ^ c64_8);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m8 ^ c64_15);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m9 ^ c64_0);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m0 ^ c64_9);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m5 ^ c64_7);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m7 ^ c64_5);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m2 ^ c64_4);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m4 ^ c64_2);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m10 ^ c64_15);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m15 ^ c64_10);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m14 ^ c64_1);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m1 ^ c64_14);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m11 ^ c64_12);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m12 ^ c64_11);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m6 ^ c64_8);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m8 ^ c64_6);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m3 ^ c64_13);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m13 ^ c64_3);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m2 ^ c64_12);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m12 ^ c64_2);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m6 ^ c64_10);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m10 ^ c64_6);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m0 ^ c64_11);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m11 ^ c64_0);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m8 ^ c64_3);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m3 ^ c64_8);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m4 ^ c64_13);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m13 ^ c64_4);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m7 ^ c64_5);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m5 ^ c64_7);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m15 ^ c64_14);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m14 ^ c64_15);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m1 ^ c64_9);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m9 ^ c64_1);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m12 ^ c64_5);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m5 ^ c64_12);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m1 ^ c64_15);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m15 ^ c64_1);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m14 ^ c64_13);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m13 ^ c64_14);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m4 ^ c64_10);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m10 ^ c64_4);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m0 ^ c64_7);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m7 ^ c64_0);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m6 ^ c64_3);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m3 ^ c64_6);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m9 ^ c64_2);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m2 ^ c64_9);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m8 ^ c64_11);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m11 ^ c64_8);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m13 ^ c64_11);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m11 ^ c64_13);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m7 ^ c64_14);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m14 ^ c64_7);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m12 ^ c64_1);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m1 ^ c64_12);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m3 ^ c64_9);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m9 ^ c64_3);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m5 ^ c64_0);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m0 ^ c64_5);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m15 ^ c64_4);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m4 ^ c64_15);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m8 ^ c64_6);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m6 ^ c64_8);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m2 ^ c64_10);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m10 ^ c64_2);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m6 ^ c64_15);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m15 ^ c64_6);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m14 ^ c64_9);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m9 ^ c64_14);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m11 ^ c64_3);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m3 ^ c64_11);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m0 ^ c64_8);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m8 ^ c64_0);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m12 ^ c64_2);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m2 ^ c64_12);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m13 ^ c64_7);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m7 ^ c64_13);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m1 ^ c64_4);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m4 ^ c64_1);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m10 ^ c64_5);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m5 ^ c64_10);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m10 ^ c64_2);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m2 ^ c64_10);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m8 ^ c64_4);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m4 ^ c64_8);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m7 ^ c64_6);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m6 ^ c64_7);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m1 ^ c64_5);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m5 ^ c64_1);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m15 ^ c64_11);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m11 ^ c64_15);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m9 ^ c64_14);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m14 ^ c64_9);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m3 ^ c64_12);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m12 ^ c64_3);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m13 ^ c64_0);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m0 ^ c64_13);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m0 ^ c64_1);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m1 ^ c64_0);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m2 ^ c64_3);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m3 ^ c64_2);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m4 ^ c64_5);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m5 ^ c64_4);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m6 ^ c64_7);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m7 ^ c64_6);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m8 ^ c64_9);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m9 ^ c64_8);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m10 ^ c64_11);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m11 ^ c64_10);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m12 ^ c64_13);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m13 ^ c64_12);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m14 ^ c64_15);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m15 ^ c64_14);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m14 ^ c64_10);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m10 ^ c64_14);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m4 ^ c64_8);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m8 ^ c64_4);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m9 ^ c64_15);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m15 ^ c64_9);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m13 ^ c64_6);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m6 ^ c64_13);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m1 ^ c64_12);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m12 ^ c64_1);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m0 ^ c64_2);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m2 ^ c64_0);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m11 ^ c64_7);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m7 ^ c64_11);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m5 ^ c64_3);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m3 ^ c64_5);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m11 ^ c64_8);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m8 ^ c64_11);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m12 ^ c64_0);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m0 ^ c64_12);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m5 ^ c64_2);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m2 ^ c64_5);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m15 ^ c64_13);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m13 ^ c64_15);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m10 ^ c64_14);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m14 ^ c64_10);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m3 ^ c64_6);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m6 ^ c64_3);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m7 ^ c64_1);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m1 ^ c64_7);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m9 ^ c64_4);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m4 ^ c64_9);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m7 ^ c64_9);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m9 ^ c64_7);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m3 ^ c64_1);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m1 ^ c64_3);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m13 ^ c64_12);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m12 ^ c64_13);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m11 ^ c64_14);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m14 ^ c64_11);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m2 ^ c64_6);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m6 ^ c64_2);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m5 ^ c64_10);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m10 ^ c64_5);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m4 ^ c64_0);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m0 ^ c64_4);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m15 ^ c64_8);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m8 ^ c64_15);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m9 ^ c64_0);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m0 ^ c64_9);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m5 ^ c64_7);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m7 ^ c64_5);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m2 ^ c64_4);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m4 ^ c64_2);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m10 ^ c64_15);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m15 ^ c64_10);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m14 ^ c64_1);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m1 ^ c64_14);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m11 ^ c64_12);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m12 ^ c64_11);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m6 ^ c64_8);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m8 ^ c64_6);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m3 ^ c64_13);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m13 ^ c64_3);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                v0 = v0 + v4 + (m2 ^ c64_12);
                v12 = ((v12 ^ v0) << 32) | ((v12 ^ v0) >> 32);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 39) | ((v4 ^ v8) >> 25);
                v0 = v0 + v4 + (m12 ^ c64_2);
                v12 = ((v12 ^ v0) << 48) | ((v12 ^ v0) >> 16);
                v8 = v8 + v12;
                v4 = ((v4 ^ v8) << 53) | ((v4 ^ v8) >> 11);

                v1 = v1 + v5 + (m6 ^ c64_10);
                v13 = ((v13 ^ v1) << 32) | ((v13 ^ v1) >> 32);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 39) | ((v5 ^ v9) >> 25);
                v1 = v1 + v5 + (m10 ^ c64_6);
                v13 = ((v13 ^ v1) << 48) | ((v13 ^ v1) >> 16);
                v9 = v9 + v13;
                v5 = ((v5 ^ v9) << 53) | ((v5 ^ v9) >> 11);

                v2 = v2 + v6 + (m0 ^ c64_11);
                v14 = ((v14 ^ v2) << 32) | ((v14 ^ v2) >> 32);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 39) | ((v6 ^ v10) >> 25);
                v2 = v2 + v6 + (m11 ^ c64_0);
                v14 = ((v14 ^ v2) << 48) | ((v14 ^ v2) >> 16);
                v10 = v10 + v14;
                v6 = ((v6 ^ v10) << 53) | ((v6 ^ v10) >> 11);

                v3 = v3 + v7 + (m8 ^ c64_3);
                v15 = ((v15 ^ v3) << 32) | ((v15 ^ v3) >> 32);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 39) | ((v7 ^ v11) >> 25);
                v3 = v3 + v7 + (m3 ^ c64_8);
                v15 = ((v15 ^ v3) << 48) | ((v15 ^ v3) >> 16);
                v11 = v11 + v15;
                v7 = ((v7 ^ v11) << 53) | ((v7 ^ v11) >> 11);

                v0 = v0 + v5 + (m4 ^ c64_13);
                v15 = ((v15 ^ v0) << 32) | ((v15 ^ v0) >> 32);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 39) | ((v5 ^ v10) >> 25);
                v0 = v0 + v5 + (m13 ^ c64_4);
                v15 = ((v15 ^ v0) << 48) | ((v15 ^ v0) >> 16);
                v10 = v10 + v15;
                v5 = ((v5 ^ v10) << 53) | ((v5 ^ v10) >> 11);

                v1 = v1 + v6 + (m7 ^ c64_5);
                v12 = ((v12 ^ v1) << 32) | ((v12 ^ v1) >> 32);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 39) | ((v6 ^ v11) >> 25);
                v1 = v1 + v6 + (m5 ^ c64_7);
                v12 = ((v12 ^ v1) << 48) | ((v12 ^ v1) >> 16);
                v11 = v11 + v12;
                v6 = ((v6 ^ v11) << 53) | ((v6 ^ v11) >> 11);

                v2 = v2 + v7 + (m15 ^ c64_14);
                v13 = ((v13 ^ v2) << 32) | ((v13 ^ v2) >> 32);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 39) | ((v7 ^ v8) >> 25);
                v2 = v2 + v7 + (m14 ^ c64_15);
                v13 = ((v13 ^ v2) << 48) | ((v13 ^ v2) >> 16);
                v8 = v8 + v13;
                v7 = ((v7 ^ v8) << 53) | ((v7 ^ v8) >> 11);

                v3 = v3 + v4 + (m1 ^ c64_9);
                v14 = ((v14 ^ v3) << 32) | ((v14 ^ v3) >> 32);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 39) | ((v4 ^ v9) >> 25);
                v3 = v3 + v4 + (m9 ^ c64_1);
                v14 = ((v14 ^ v3) << 48) | ((v14 ^ v3) >> 16);
                v9 = v9 + v14;
                v4 = ((v4 ^ v9) << 53) | ((v4 ^ v9) >> 11);

                m_state[0] ^= v0 ^ v8;
                m_state[1] ^= v1 ^ v9;
                m_state[2] ^= v2 ^ v10;
                m_state[3] ^= v3 ^ v11;
                m_state[4] ^= v4 ^ v12;
                m_state[5] ^= v5 ^ v13;
                m_state[6] ^= v6 ^ v14;
                m_state[7] ^= v7 ^ v15;
            }

            virtual array<byte>^ GetResult() override
            {
                return Converters::ConvertULongsToBytesSwapOrder(m_state, 0, m_hashSize/8);
            }

            virtual void Finish() override
            {
                ulong bits = m_processedBytes * 8;

                if (m_buffer_pos == 111) 
                {
                    m_processedBytes -= 1; 
                    if (m_hashSize == 48) 
                        TransformBytes(ending, 2, 1);
                    else
                        TransformBytes(ending, 3, 1);
                }
                else 
                {
                    if (m_buffer_pos < 111) 
                    {
                        if (m_buffer_pos == 0) 
                            m_nullt=true;
                        m_processedBytes -= 111 - m_buffer_pos;
                        TransformBytes(padding, 0, 111 - m_buffer_pos);
                    }
                    else 
                    { 
                        m_processedBytes -= 128 - m_buffer_pos; 
                        TransformBytes(padding, 0, 128 - m_buffer_pos);
                        m_processedBytes -= 111;
                        TransformBytes(padding, 1, 111);
                        m_nullt = true;
                    }
                    if (m_hashSize == 48) 
                        TransformBytes(ending, 0, 1);
                    else
                        TransformBytes(ending, 1, 1);
                    m_processedBytes -= 1;
                }

                m_processedBytes -= 16;

                array<byte>^ msg = gcnew array<byte>(16);
                msg[8] = (byte)(bits >> 56);
                msg[9] = (byte)(bits >> 48);
                msg[10] = (byte)(bits >> 40);
                msg[11] = (byte)(bits >> 32);
                msg[12] = (byte)(bits >> 24);
                msg[13] = (byte)(bits >> 16);
                msg[14] = (byte)(bits >> 8);
                msg[15] = (byte)bits;

                TransformBytes(msg, 0, 16);  
            }

        public:

            Blake512(int a_hashSize)
                : Blake(a_hashSize)
            {
                Debug::Assert((a_hashSize == 48) || (a_hashSize == 64));

                m_state = gcnew array<ulong>(8);
                m_buffer = gcnew array<byte>(128);

                Initialize();
            }

            virtual void Initialize() override
            {
                if (m_hashSize == 48) 
                    Buffer::BlockCopy(m_initial_state_384, 0, m_state, 0, 64);      
                else 
                    Buffer::BlockCopy(m_initial_state_512, 0, m_state, 0, 64);

                Array::Clear(m_buffer, 0, 128);

                Blake::Initialize();
            }

            virtual void TransformBytes(array<byte>^ a_data, int a_index, int a_length) override
            {
                if ((a_length == 0) && (m_buffer_pos != 128))
                    return;

                int left = m_buffer_pos;
                int fill = 128 - left;

                if(left && ((a_length & 0x7F) >= fill)) 
                {
                    Array::Copy(a_data, a_index, m_buffer, left, fill);
                    m_processedBytes += fill;

                    TransformBlock(m_buffer, 0);
                    a_index += fill;
                    a_length  -= fill; 

                    left = 0;
                }

                while(a_length >= 128) 
                {
                    m_processedBytes += 128;
                    TransformBlock(a_data, a_index);
                    a_index += 128;
                    a_length  -= 128;
                }

                if(a_length > 0) 
                {
                    Array::Copy(a_data, a_index, m_buffer, left, a_length);
                    m_buffer_pos = left + a_length;
                    m_processedBytes += a_length;
                }
                else
                    m_buffer_pos = 0;
            }
    };
}